/**   
 * @Title: AbstarctClient.java 
 * @Package com.org.net.tcp 
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author cssuger@163.com   
 * @date 2017年2月9日 下午1:15:52 
 * @version V1.0   
 */
package com.bicon.base.data.common.net.tcp;

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;




/** 
 *@ClassName: AbstarctClient 
 *@Description: TODO(这里用一句话描述这个类的作用) 
 *@author cssuger@163.com 
 *@date 2017年2月9日 下午1:15:52  
 */
public abstract class AbstarctClient {

	private Logger logger = LoggerFactory.getLogger(AbstarctClient.class);
	
	private String host;
	
	private int port;
	
	private volatile boolean closed = false;
	
	private volatile  NioEventLoopGroup group;
	
	private volatile Bootstrap bootstrap;
	
	
	
    public  AbstarctClient(String host,int port){
		this.host = host;
		this.port = port;
		group  = new NioEventLoopGroup();
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}
    
    public void connection(){
    	try{
    		bootstrap = new Bootstrap();
        	bootstrap.group(group);
        	//EpollSocketChannel
        	bootstrap.channel(NioSocketChannel.class);
//        	bootstrap.option(ChannelOption.AUTO_CLOSE, true);
//    		// 连接时间
//        	bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60000);
//    		// 长连接
//        	bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        	bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        	//bootstrap.handler(new ServiceChannle().getServiceChannelInitializer());
        	initChannel(bootstrap);
    		//doConnect();
        	doConnection();
    	}finally{
    		closeResource(group);
    	}
    	
		
    }
    
    public void doConnection(){
    	if (closed) {
			return;
		}
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, this.port));
		try {
			future = future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
//    public void doConnect()  {
//		if (closed) {
//			return;
//		}
//		ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, this.port));
//		future.addListener(new ChannelFutureListener() {
//			public void operationComplete(ChannelFuture f) throws Exception {
//				if (f.isSuccess()) {
//					logger.info("Started Tcp Client: " );
//				} else {
//					logger.info("Started Tcp Client Failed: " );
//					f.channel().eventLoop().schedule(new Runnable() {
//						
//						@Override
//						public void run() {
//						
//						 // doConnect();
//								
//							
//						}
//					}, 10, TimeUnit.SECONDS);
//				}
//			}
//		});
//	}
    
    private void closeResource(NioEventLoopGroup group){
    	closed = true;
    	if (null != group) {
			try {
				// 关闭引导器并释放资源，包括线程池
				group.shutdownGracefully().sync();
			//	logger.info("即便是连接不上服务器端,也要将其进行关闭");
			} catch (InterruptedException e) {
			//	logger.info("上传客户端连接socket服务器报错："+e);
				e.printStackTrace();
			}
		}
    }
    
    protected abstract void initChannel(Bootstrap bootstrap);
    
    
}
